#ifndef __ScintillaWX_h__
#define __ScintillaWX_h__

#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "Platform.h"

#include "Scintilla.h"
#include "XPM.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "Accessor.h"
#endif
#include "ContractionState.h"
#include "CellBuffer.h"
#include "CallTip.h"
#include "KeyMap.h"
#include "Indicator.h"
#include "LineMarker.h"
#include "Style.h"
#include "ViewStyle.h"
#include "AutoComplete.h"
#include "CharClassify.h"
#include "RESearch.h"
#include "Document.h"
#include "Editor.h"
#include "ScintillaBase.h"

#include <wx/dataobj.h>
#include <wx/dnd.h>
#include <wx/timer.h>

#ifdef WXMAKINGDLL_SCI
#define WXDLLIMPEXP_SCI WXEXPORT
#elif defined(WXUSINGDLL)
#define WXDLLIMPEXP_SCI WXIMPORT
#else
#define WXDLLIMPEXP_SCI
#endif


#ifdef SCI_NAMESPACE
#ifndef SCI_NAMESPACE_PREFIX
#define SCI_NAMESPACE_PREFIX( x ) Scintilla::x
#endif
#else
#ifndef SCI_NAMESPACE_PREFIX
#define SCI_NAMESPACE_PREFIX( x ) x
#endif
#endif



class wxScintilla;
class ScintillaWX;




#if wxUSE_DRAG_AND_DROP
class wxSCIDropTarget : public wxTextDropTarget {
  public:
    void SetScintilla( ScintillaWX* swx ) {
      m_swx = swx;
    }

    bool OnDropText( wxCoord x, wxCoord y, const wxString& data );
    wxDragResult OnEnter( wxCoord x, wxCoord y, wxDragResult def );
    wxDragResult OnDragOver( wxCoord x, wxCoord y, wxDragResult def );
    void OnLeave();

  private:
    ScintillaWX* m_swx;
};
#endif



class ScintillaWX : public SCI_NAMESPACE_PREFIX( ScintillaBase ) {
  public:
    ScintillaWX( wxScintilla * win );
    ~ScintillaWX();
    virtual void Initialise();
    virtual void Finalise();
    virtual void StartDrag();
    virtual bool SetIdle( bool on );
    virtual void SetMouseCapture( bool on );
    virtual bool HaveMouseCapture();
    virtual void ScrollText( int linesToMove );
    virtual void SetVerticalScrollPos();
    virtual void SetHorizontalScrollPos();
    virtual bool ModifyScrollBars( int nMax, int nPage );
    virtual void Copy();
    virtual void Paste();
    virtual void CopyToClipboard( const SCI_NAMESPACE_PREFIX( SelectionText ) &selectedText );
    virtual void CreateCallTipWindow( SCI_NAMESPACE_PREFIX( PRectangle ) rc );
    virtual void AddToPopUp( const char *label, int cmd = 0, bool enabled = true );
    virtual void ClaimSelection();
    virtual sptr_t DefWndProc( unsigned int iMessage,
                               uptr_t wParam,
                               sptr_t lParam );
    virtual sptr_t WndProc( unsigned int iMessage,
                            uptr_t wParam,
                            sptr_t lParam );
    static sptr_t DirectFunction( ScintillaWX * wxsci,
                                  unsigned int iMessage,
                                  uptr_t wParam,
                                  sptr_t lParam );
    virtual void NotifyChange();
    virtual void NotifyParent( SCI_NAMESPACE_PREFIX( SCNotification ) scn );
    virtual void NotifyFocus( bool focus );
    enum { timersCount = tickPlatform };
    wxTimer* timers[timersCount];
    virtual bool FineTickerAvailable();
    virtual bool FineTickerRunning( TickReason reason );
    virtual void FineTickerStart( TickReason reason, int millis, int tolerance );
    virtual void FineTickerCancel( TickReason reason );
    virtual void CancelModes();
    virtual void UpdateSystemCaret();
    void DoPaint( wxDC * dc, wxRect rect );
    void DoHScroll( int type, int pos );
    void DoVScroll( int type, int pos );
    void DoSize( int width, int height );
    void DoLoseFocus();
    void DoGainFocus();
    void DoSysColourChange();
    void DoLeftButtonDown( SCI_NAMESPACE_PREFIX( Point ) pt, unsigned int curTime, bool shift, bool ctrl, bool alt );
    void DoLeftButtonUp( SCI_NAMESPACE_PREFIX( Point ) pt, unsigned int curTime, bool ctrl );
    void DoLeftButtonMove( SCI_NAMESPACE_PREFIX( Point ) pt );
    void DoMiddleButtonUp( SCI_NAMESPACE_PREFIX( Point ) pt );
    enum wxMouseWheelAxis {
      wxMOUSE_WHEEL_VERTICAL,
      wxMOUSE_WHEEL_HORIZONTAL
    };
    void DoMouseWheel( wxMouseWheelAxis axis, int rotation, int delta,
                       int linesPerAction, int columnsPerAction,
                       bool ctrlDown, bool isPageScroll );
    void DoAddChar( int key );
    int  DoKeyDown( const wxKeyEvent & event, bool * consumed );
    void DoTick() { Tick(); }
    void DoOnIdle( wxIdleEvent & evt );
    void DoOnTimer( wxTimerEvent & evt );
    #if wxUSE_DRAG_AND_DROP
    bool DoDropText( long x, long y, const wxString & data );
    wxDragResult DoDragEnter( wxCoord x, wxCoord y, wxDragResult def );
    wxDragResult DoDragOver( wxCoord x, wxCoord y, wxDragResult def );
    void DoDragLeave();
    #endif
    void DoCommand( int ID );
    void DoContextMenu( SCI_NAMESPACE_PREFIX( Point ) pt );
    void DoOnListBox();
    void FullPaint();
    void FullPaintDC( wxDC * dc );
    bool CanPaste();
    bool GetHideSelection() { return view.hideSelection; }
    void DoScrollToLine( int line );
    void DoScrollToColumn( int column );
    void ClipChildren( wxDC & dc, SCI_NAMESPACE_PREFIX( PRectangle ) rect );
    void SetUseAntiAliasing( bool useAA );
    bool GetUseAntiAliasing();
  private:
    bool                capturedMouse;
    bool                focusEvent;
    wxScintilla*        sci;
    #if wxUSE_DRAG_AND_DROP
    wxSCIDropTarget*    dropTarget;
    wxDragResult        dragResult;
    bool                dragRectangle;
    #endif
    int                 wheelVRotation;
    int                 wheelHRotation;
    bool HasCaretSizeChanged();
    bool CreateSystemCaret();
    bool DestroySystemCaret();
    friend class wxSCICallTipContent;
};

#endif
